<?php

namespace App\Http\Middleware\Api;


use App\Http\Middleware\Middleware;
use Closure;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Http\Request;
use Exception;

/**
 * 用户鉴权中间件
 * Class ApiTokenCheckMiddleware
 * @package App\Http\Middleware\Api
 */
class TokenCheckMiddleware extends Middleware
{
    /**
     * @param Request $request 请求Request对象
     * @param Closure $next
     * @return mixed
     * @throws Exception
     */
	public function handle(Request $request, Closure $next): mixed
    {
        // 定义来源
        defined('APP_USER_TOKEN_SRC') or define('APP_USER_TOKEN_SRC', 2);

		$tokenStr = $request->header('SC-API-TOKEN');
		if (!$request->header('SC-API-TOKEN')) {
			$tokenStr = $request->input('SC-API-TOKEN', "");
			if (!$tokenStr) {
				$this->returnError();
			}
		}

		try {
			$token = Crypt::decryptString($tokenStr);
			$userObj = Auth::user($token);
			if (!$userObj) {
				$this->returnError(LOGIN_FAIL);
			}

			//如果是超级管理员则不检测权限
			if ($userObj['is_supper_admin'] != 1) {
				//检查用户权限
				$authList = $userObj['authList'] ?: [];
				if (!$this->CheckAuthList($authList)) {
					$this->returnError(RETURN_FAIL);
				}
			}

			//更新TOKEN访问信息
			$info = $this->updateTokenInfo($token, $userObj['tokenInfo']);
			if ($info['code'] !== RETURN_SUCCESS) {
                $this->returnError(RETURN_CHECK_TOKEN_FAIL,$info['msg'] . 'TOKEN:' . $token);
			}

			defined('APP_USER_TOKEN') or define('APP_USER_TOKEN', $token);
			// 定义来源
			defined('APP_USER_TOKEN_SRC') or define('APP_USER_TOKEN_SRC', 1);
			return $next($request);
		} catch (\Throwable $e) {
			if (config('app.debug')) {
				$this->returnError(RETURN_FAIL, $e->getMessage());
			} else {
				$this->returnError();
			}
		}
	}

    /**
     * 检查权限列表
     * @param array $authList
     * @return bool
     */
	public function CheckAuthList(array $authList = []): bool
    {
		//在此处填写权限判定逻辑

		return true;
	}

    /**
     * 更新用户TOKEN信息
     * @param string $token 用户令牌
     * @param array $tokenInfo 更新的令牌信息
     * @return void
     * @throws Exception
     */
	public function updateTokenInfo(string $token, array $tokenInfo = [])
    {
		if ($tokenInfo['is_invalid'] == 1 || $tokenInfo['expire_time'] < time() || $tokenInfo['call_num'] < 1) {
			$this->returnError(RETURN_CHECK_TOKEN_FAIL, 'TOKEN已失效，请重新登录');
		}
        //在此处填写更新TOKEN逻辑

	}
}
